package dongze.com.ckdj.activity;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.DataSetObservable;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ExpandableListView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.ButterKnife;
import dongze.com.ckdj.R;
import dongze.com.ckdj.adapter.ImageUploadListAdapter;
import dongze.com.ckdj.persistence.dao.DaoSession;
import dongze.com.ckdj.service.IImageUploadCallback;
import dongze.com.ckdj.service.IImageUploadService;
import dongze.com.ckdj.service.ImageUploadService;
import dongze.com.ckdj.service.ImageUploadTask;
import dongze.com.ckdj.util.MyLog;

/**
 * Created by fanqwz on 2017/7/24.
 */

public class ImageUploadActivity extends BaseActivity {
    private static final String TAG = ImageUploadActivity.class.getSimpleName();
    private IImageUploadService service;
    private List<ImageUploadListAdapter.ImageListItem> uploadingList = new ArrayList<>();
    private List<ImageUploadListAdapter.ImageListItem> unStartList = new ArrayList<>();
    private List<ImageUploadListAdapter.ImageListItem> finishedList = new ArrayList<>();
    private DataSetObservable observable = new DataSetObservable();
    private Handler handler;
    @Inject
    DaoSession daoSession;

    private IImageUploadCallback callback = new IImageUploadCallback.Stub() {
        @Override
        public void onTaskProgressChanged(final ImageUploadTask task, final int progress) throws RemoteException {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    for (ImageUploadListAdapter.ImageListItem t :
                            uploadingList) {
                        if (t.getTask().getId() == task.getId()) {
                            t.getTask().setUploadProgress(progress);
                            t.getTask().setState(task.getState());
                        }
                    }
                    observable.notifyChanged();
                }
            });
        }

        @Override
        public void onTaskFinished(final ImageUploadTask task) throws RemoteException {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    for (ImageUploadListAdapter.ImageListItem t :
                            uploadingList) {
                        if (t.getTask().getId() == task.getId()) {
                            uploadingList.remove(t);
                            break;
                        }
                    }
                    updateTask(task);
                    observable.notifyInvalidated();
                }
            });
        }

        @Override
        public void onTaskFailed(final ImageUploadTask task) throws RemoteException {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    for (ImageUploadListAdapter.ImageListItem t :
                            uploadingList) {
                        if (t.getTask().getId() == task.getId()) {
                            uploadingList.remove(t);
                            break;
                        }
                    }
                    updateTask(task);
                    observable.notifyInvalidated();
                }
            });
        }

        @Override
        public void onTaskAdded(final ImageUploadTask task) throws RemoteException {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    for (ImageUploadListAdapter.ImageListItem t :
                            unStartList) {
                        if (t.getTask().getId() == task.getId()) {
                            unStartList.remove(t);
                            break;
                        }
                    }

                    updateTask(task);
                    observable.notifyInvalidated();
                }
            });
        }

        @Override
        public void onTaskDeleted(final ImageUploadTask task) throws RemoteException {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    for (ImageUploadListAdapter.ImageListItem t :
                            finishedList) {
                        if (t.getTask().getId() == task.getId()) {
                            finishedList.remove(t);
                            break;
                        }
                    }
                    observable.notifyInvalidated();
                }
            });
        }

        @Override
        public void onTaskCanceled(final ImageUploadTask task) throws RemoteException {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    for (ImageUploadListAdapter.ImageListItem t :
                            uploadingList) {
                        if (t.getTask().getId() == task.getId()) {
                            uploadingList.remove(t);
                            break;
                        }
                    }
                    updateTask(task);
                    observable.notifyInvalidated();
                }
            });
        }

        @Override
        public void onNetStateChanged(int state) throws RemoteException {

        }
    };

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            ImageUploadActivity.this.service = IImageUploadService.Stub.asInterface(service);
            try {
                ImageUploadActivity.this.service.addCallback(callback);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

            updateData();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            service = null;
        }
    };

    @BindView(R.id.expandableListView)
    ExpandableListView expandableListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getAppCompenent().inject(this);
        handler = new Handler(getMainLooper());
        setContentView(R.layout.activity_image_upload);
        ButterKnife.bind(this);
        expandableListView.setChildDivider(null);
        bindService(new Intent(this, ImageUploadService.class), conn, BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        unbindService(conn);
        super.onDestroy();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.image_all_upload, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.all_upload) {
            MyLog.i(TAG, "onOptionsItemSelected: 未上传：" + unStartList.size());
            for (ImageUploadListAdapter.ImageListItem task : unStartList) {
                action.restart(task.getTask().getId());
            }
        } else if (item.getItemId() == R.id.delete_finished) {
            action.deleteAllFinished();
        } else {
            return super.onOptionsItemSelected(item);
        }

        return true;
    }

    private void updateData() {
        try {
            ImageUploadTask[] tasks = service.getCurrentTasks();
            for (ImageUploadTask t :
                    tasks) {
                uploadingList.add(ImageUploadListAdapter.createImageListItem(t, daoSession));

            }
            ImageUploadTask[] unStart = service.getUnstartTasks();
            for (ImageUploadTask t :
                    unStart) {
                unStartList.add(ImageUploadListAdapter.createImageListItem(t, daoSession));
            }

            ImageUploadTask[] finished = service.getHistoryTask(0, 100);
            for (ImageUploadTask t :
                    finished) {
                finishedList.add(ImageUploadListAdapter.createImageListItem(t, daoSession));
            }
            showUI();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private void updateTask(ImageUploadTask task) {
        switch (task.getState()) {
            case INIT:
            case Undefined:
                unStartList.add(ImageUploadListAdapter.createImageListItem(task, daoSession));
                break;
            case QUEUED:
            case Waiting:
            case Uploading:
                uploadingList.add(ImageUploadListAdapter.createImageListItem(task, daoSession));
                break;
            case Finished:
                finishedList.add(ImageUploadListAdapter.createImageListItem(task, daoSession));
                break;
        }
    }

    private void showUI() {
        expandableListView.setAdapter(new ImageUploadListAdapter(uploadingList, unStartList, finishedList, observable, action, getResources(), daoSession));
//        expandableListView.expandGroup(0);
//        expandableListView.expandGroup(1);
    }

    private IImageUploadAction action = new IImageUploadAction() {
        @Override
        public void restart(long id) {
            if (service != null) {
                try {
                    service.reStartTask(id);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void delete(long id) {
            if (service != null) {
                try {
                    service.deleteTask(id);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void deleteAllFinished() {
            if (service != null) {
                for (ImageUploadListAdapter.ImageListItem t :
                        finishedList) {
                    try {
                        service.deleteTask(t.getTask().getId());
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        @Override
        public void forceStart(long id) {
            if (service != null) {
                try {
                    service.forceStart(id);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void cancel(long id) {
            if (service != null) {
                try {
                    service.cancelTask(id);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    public interface IImageUploadAction {
        void restart(long id);

        void delete(long id);

        void deleteAllFinished();

        void forceStart(long id);

        void cancel(long id);
    }
}
